package com.axinfu.util;

import java.util.Arrays;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * StringUtil
 *
 * @author zjn
 * @since 2022/3/23
 */
public class StringUtil {

    private StringUtil() {
    }

    /**
     * 格式化字符串为指定长度
     * 若长度不够则用指定字符从指定下标补充
     * 若超出指定长度，并根据是否指定截断进行截断处理
     *
     * @param str        待格式化字符串
     * @param fillLength 输出长度
     * @param fillChar   补位字符
     * @param fillIndex  插入下标，默认为0，即为从左侧开始插入，指定为length即可实现从右侧插入
     * @param isTrancate 超出长度是否截断，默认为false
     * @return String
     */
    public static String format2length(String str, int fillLength, String fillChar, int fillIndex, boolean isTrancate) {
        str = EmptyUtil.isNotEmptyOrDefault(str, "");
        int strLength = str.length();
        fillIndex = Math.min(fillIndex, strLength);
        int l = fillLength - strLength;
        if (l > 0) {
            StringBuilder fillStr = new StringBuilder();
            for (int i = 0; i < l; i++) {
                fillStr.append(fillChar);
            }
            str = str.substring(0, fillIndex) + fillStr + str.substring(fillIndex);
        } else {
            if (isTrancate) {
                str = str.substring(0, fillLength);
            }
        }

        return str;
    }

    /**
     * 格式化字符串为指定长度
     * 若长度不够则用指定字符从指定下标补充
     * 若超出指定长度，并根据是否指定截断进行截断处理
     *
     * @param str        待格式化字符串
     * @param fillLength 输出长度
     * @param fillChar   补位字符
     * @param fillIndex  插入下标，默认为0，即为从左侧开始插入，指定为length即可实现从右侧插入
     * @return String
     */
    public static String format2length(String str, int fillLength, String fillChar, int fillIndex) {
        return format2length(str, fillLength, fillChar, fillIndex, false);
    }

    /**
     * 格式化字符串为指定长度
     * 若长度不够则用指定字符从指定下标补充
     * 若超出指定长度，并根据是否指定截断进行截断处理
     *
     * @param str        待格式化字符串
     * @param fillLength 输出长度
     * @param fillChar   补位字符
     * @return String
     */
    public static String format2length(String str, int fillLength, String fillChar) {
        return format2length(str, fillLength, fillChar, 0);
    }

    /**
     * 格式化字符串为指定长度
     * 若长度不够则用指定字符从指定下标补充
     * 若超出指定长度，并根据是否指定截断进行截断处理
     *
     * @param str        待格式化字符串
     * @param fillLength 输出长度
     * @return String
     */
    public static String format2length(String str, int fillLength) {
        return format2length(str, fillLength, " ");
    }

    /**
     * 添加字符串最后一个后缀，已存在不添加不存在自动添加
     *
     * @param uri    待处理字符串
     * @param suffix 后缀
     * @return 处理后的字符串
     */
    public static String addLastSuffix(String uri, String suffix) {
        if (EmptyUtil.isEmpty(uri)) {
            return null;
        }
        if (uri.endsWith(suffix)) {
            return uri;
        }
        return uri + suffix;
    }

    /**
     * 添加字符串最后一个后缀，已存在不添加不存在自动添加
     *
     * @param uri 待处理字符串
     * @return 处理后的字符串
     */
    public static String addLastSuffix(String uri) {
        return addLastSuffix(uri, "/");
    }

    private static final Pattern LINE_PATTERN = Pattern.compile("_(\\w)");
    private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");

    /**
     * 下划线转驼峰
     *
     * @param str          str
     * @param isFirstUpper isFirstUpper
     * @return String
     */
    public static String lineToHump(String str, boolean isFirstUpper) {
        str = str.toLowerCase();
        Matcher matcher = LINE_PATTERN.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        if (isFirstUpper) {
            return sb.toString().substring(0, 1).toUpperCase() + sb.substring(1);
        } else {
            return sb.toString();
        }
    }

    /**
     * 下划线转驼峰
     *
     * @param str str
     * @return String
     */
    public static String lineToHump(String str) {
        return lineToHump(str, false);
    }

    /**
     * 驼峰转下划线
     *
     * @param str str
     * @return String
     */
    public static String humpToLine(String str) {
        Matcher matcher = HUMP_PATTERN.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 使用指定符号分隔
     *
     * @param list      list
     * @param separator 分隔符
     * @return String
     */
    public static String joinObject(Object[] list, String separator) {
        if (EmptyUtil.isEmpty(list)) {
            return "";
        }
        if (EmptyUtil.isEmpty(separator)) {
            throw new IllegalArgumentException("separator can not be null.");
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (Object s : list) {
            stringBuilder.append(separator).append(s);
        }
        if (EmptyUtil.isEmpty(stringBuilder)) {
            return "";
        }
        return stringBuilder.substring(separator.length());
    }

    /**
     * 使用指定符号分隔
     *
     * @param list list
     * @return String
     */
    public static String joinObject(Object[] list) {
        return joinObject(list, ",");
    }

    /**
     * 使用指定符号分隔
     *
     * @param list      list
     * @param separator 分隔符
     * @return String
     */
    public static String joinObject(Collection<Object> list, String separator) {
        return joinObject(list.toArray(), separator);
    }

    /**
     * 使用指定符号分隔
     *
     * @param list list
     * @return String
     */
    public static String joinObject(Collection<Object> list) {
        return joinObject(list.toArray(), ",");
    }

    /**
     * 使用指定符号分隔
     *
     * @param list      list
     * @param separator 分隔符
     * @return String
     */
    public static String join(String[] list, String separator) {
        Object[] listObj = Arrays.stream(list).toArray();
        return joinObject(listObj, separator);
    }

    /**
     * 使用指定符号分隔
     *
     * @param list list
     * @return String
     */
    public static String join(String[] list) {
        return join(list, ",");
    }

    /**
     * 使用指定符号分隔
     *
     * @param list      list
     * @param separator 分隔符
     * @return String
     */
    public static String join(Collection<String> list, String separator) {
        return joinObject(list.toArray(), separator);
    }

    /**
     * 使用指定符号分隔
     *
     * @param list list
     * @return String
     */
    public static String join(Collection<String> list) {
        return join(list, ",");
    }
}
